﻿#region Copyrights

/*
    - - - - - - - - - - - - - - - - - - - - - - -
    Nome do Arquivo : BOBase.cs
    - - - - - - - - - - - - - - - - - - - - - - -

    Sistema				    :  	LLS.Core
    Modulo				    :  	LLS.BusinessLogic.Core
    Autor				    :	Leonardo L. de Siqueira
    Data					:	28/02/2012
    Descrição  				:	Classe abstrata base para todos os objetos de modelo de negócios.
    
*/

#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LLS.DataModel.Core;
using System.Configuration;
using LLS.DataAccess.Core;

namespace LLS.BusinessLogic.Core
{
    /// <summary>
    /// Classe abstrata base para todos os objetos de modelo de negócios
    /// </summary>
    /// <typeparam name="U">Objeto com herança do tipo DMOBase</typeparam>
    public abstract class BOBase<U>
        where U : DMOBase
    {
        #region Constants

        private static readonly string _recordAudit = ConfigurationManager.AppSettings["DATA.RECORDAUDIT"];

        #endregion

        #region Fields

        private string _accountName;
        System.Reflection.ConstructorInfo _ci = null;
        private U _dataModel = null;
        private Type _type = typeof(U);
        private DAOHelper _dAOHelper = null;
        DAOGeneric<U> _dAOGeneric = null;
        DAOGeneric<DMOAudit> _dAOAudit = null;
        DAOGeneric<DMOAuditDetail> _dAOAuditDetail = null;

        #endregion

        #region Public Methods

        /// <summary>
        /// Método construtor
        /// </summary>
        /// <param name="accountName">Nome da conta que está criando o objeto de negócios.</param>
        public BOBase(string accountName)
        {
            if (string.IsNullOrEmpty(accountName)) throw new ArgumentNullException("accountName");

            _accountName = accountName;
            _ci = _type.GetConstructor(System.Type.EmptyTypes);
            _dataModel = (U)_ci.Invoke(null);
            _dAOHelper = new DAOHelper();
            _dAOGeneric = new DAOGeneric<U>();
            _dAOAudit = new DAOGeneric<DMOAudit>();
            _dAOAuditDetail = new DAOGeneric<DMOAuditDetail>();
        }

        /// <summary>
        /// Persiste um novo registro em uma tabela do banco de dados
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>
        public virtual void Save(U dataModel)
        {
            if (dataModel == null) throw new ArgumentNullException("dataModel");

            _dAOHelper.EstablishFactoryConnection();
            _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Begin);

            try
            {
                _dAOGeneric.Save(dataModel, _dAOHelper);

                #region Auditoria

                if ((!string.IsNullOrEmpty(_recordAudit)) && (_recordAudit.ToUpper() == true.ToString().ToUpper()))
                {
                    //Verifica se o modelo será auditado ou não
                    if (!dataModel.IsNotAudit())
                    {
                        string primaryKeyColumnName = dataModel.GetPrimaryKeyColumnName();
                        string primaryKey = dataModel.GetPropertiesInformation().FindByColumnName(primaryKeyColumnName).PropertyValue.ToString();

                        DMOAudit dMOAudit = new DMOAudit();
                        dMOAudit.Action = DMOAudit.ActionType.Save;
                        dMOAudit.TableName = dataModel.GetTableName();
                        dMOAudit.PrimaryKey = string.Concat(primaryKeyColumnName, "=", primaryKey);
                        dMOAudit.ActionDate = DateTime.Now;
                        dMOAudit.ActionUser = _accountName;
                        _dAOAudit.Save(dMOAudit, _dAOHelper);

                        DMOBase.PropertiesInformation propertiesInformation = dataModel.GetPropertiesInformation();

                        foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
                        {
                            if (!propertyInformation.ColumnAttribute.NotAudit)
                            {
                                object oldValue = null;
                                object newValue = propertyInformation.ToString();

                                DMOAuditDetail dMOAuditDetail = new DMOAuditDetail();
                                dMOAuditDetail.AuditId = dMOAudit.Id;
                                dMOAuditDetail.ColumnName = propertyInformation.ColumnAttribute.Name;
                                dMOAuditDetail.OldValue = (oldValue != null) ? oldValue.ToString() : null;
                                dMOAuditDetail.NewValue = (newValue != null) ? newValue.ToString() : null;
                                _dAOAuditDetail.Save(dMOAuditDetail, _dAOHelper);
                            }
                        }
                    }
                }

                #endregion

                _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Commit);
            }
            catch
            {
                _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Rollback);
                throw;
            }
        }

        /// <summary>
        /// Carrega um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>
        /// <returns>Lista de modelo de dados carregados</returns>
        public virtual List<U> Load(Filter<U> filter)
        {
            return _dAOGeneric.Load(filter);
        }

        /// <summary>
        /// Carrega um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>
        /// <param name="startRowIndex">posição inicial na base de dados para início da carga</param>
        /// <param name="maximumRows">Quantidade máxima de registros permitidos para retorno</param>
        /// <returns>Lista de modelo de dados carregados</returns>
        public virtual List<U> Load(Filter<U> filter, Int64 startRowIndex, Int64 maximumRows)
        {
            return _dAOGeneric.Load(filter, startRowIndex, maximumRows);
        }

        /// <summary>
        /// Carrega todos os registros de uma tabela do banco de dados
        /// </summary>
        /// <returns>Lista de modelo de dados carregados</returns>
        public virtual List<U> LoadAll()
        {
            return _dAOGeneric.LoadAll();
        }

        /// <summary>
        /// Atualiza um registro já existente em uma tabela do banco de dados
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>
        public virtual void Update(U dataModel)
        {
            if (dataModel == null) throw new ArgumentNullException("dataModel");

            _dAOHelper.EstablishFactoryConnection();
            _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Begin);

            try
            {
                #region Auditoria

                if ((!string.IsNullOrEmpty(_recordAudit)) && (_recordAudit.ToUpper() == true.ToString().ToUpper()))
                {
                    //Verifica se o modelo será auditado ou não
                    if (!dataModel.IsNotAudit())
                    {
                        string primaryKeyColumnName = dataModel.GetPrimaryKeyColumnName();
                        string primaryKeyPropertyName = dataModel.GetPrimaryKeyPropertyName();
                        object primaryKeyObject = dataModel.GetPropertiesInformation().FindByColumnName(primaryKeyColumnName).PropertyValue;
                        string primaryKeyString = primaryKeyObject.ToString();
                        List<U> models = _dAOGeneric.Load(new Filter<U>().EqualTo(primaryKeyPropertyName, primaryKeyObject));

                        foreach (U model in models)
                        {
                            DMOAudit dMOAudit = new DMOAudit();
                            dMOAudit.Action = DMOAudit.ActionType.Update;
                            dMOAudit.TableName = dataModel.GetTableName();
                            dMOAudit.PrimaryKey = string.Concat(primaryKeyColumnName, "=", primaryKeyString);
                            dMOAudit.ActionDate = DateTime.Now;
                            dMOAudit.ActionUser = _accountName;
                            _dAOAudit.Save(dMOAudit, _dAOHelper);

                            DMOBase.PropertiesInformation propertiesInformation = dataModel.GetPropertiesInformation();

                            foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
                            {
                                if (!propertyInformation.ColumnAttribute.NotAudit)
                                {
                                    object oldValue = model.GetPropertiesInformation().FindByColumnName(propertyInformation.ColumnAttribute.Name).ToString();
                                    object newValue = propertyInformation.ToString();

                                    if (oldValue != newValue /* || !oldValue.Equals(newValue)*/)
                                    {
                                        DMOAuditDetail dMOAuditDetail = new DMOAuditDetail();
                                        dMOAuditDetail.AuditId = dMOAudit.Id;
                                        dMOAuditDetail.ColumnName = propertyInformation.ColumnAttribute.Name;
                                        dMOAuditDetail.OldValue = (oldValue != null) ? oldValue.ToString() : null;
                                        dMOAuditDetail.NewValue = (newValue != null) ? newValue.ToString() : null;
                                        _dAOAuditDetail.Save(dMOAuditDetail, _dAOHelper);
                                    }
                                }
                            }
                        }
                    }
                }

                #endregion

                _dAOGeneric.Update(dataModel, _dAOHelper);
                _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Commit);
            }
            catch
            {
                _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Rollback);
                throw;
            }
        }

        /// <summary>
        /// Exclui um ou mais registros em uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a exclusão</param>
        public virtual void Delete(Filter<U> filter)
        {
            _dAOHelper.EstablishFactoryConnection();
            _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Begin);

            try
            {
                #region Auditoria

                if ((!string.IsNullOrEmpty(_recordAudit)) && (_recordAudit.ToUpper() == true.ToString().ToUpper()))
                {
                    //Verifica se o modelo será auditado ou não
                    if (!_dataModel.IsNotAudit())
                    {
                        string primaryKeyColumnName = _dataModel.GetPrimaryKeyColumnName();
                        List<U> models = _dAOGeneric.Load(filter);

                        foreach (U model in models)
                        {
                            DMOAudit dMOAudit = new DMOAudit();
                            string primaryKey = model.GetPropertiesInformation().FindByColumnName(primaryKeyColumnName).PropertyValue.ToString();

                            dMOAudit.Action = DMOAudit.ActionType.Delete;
                            dMOAudit.TableName = _dataModel.GetTableName();
                            dMOAudit.PrimaryKey = string.Concat(primaryKeyColumnName, "=", primaryKey);
                            dMOAudit.ActionDate = DateTime.Now;
                            dMOAudit.ActionUser = _accountName;
                            _dAOAudit.Save(dMOAudit, _dAOHelper);

                            DMOBase.PropertiesInformation propertiesInformation = _dataModel.GetPropertiesInformation();

                            foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
                            {
                                if (!propertyInformation.ColumnAttribute.NotAudit)
                                {
                                    object oldValue = model.GetPropertiesInformation().FindByColumnName(propertyInformation.ColumnAttribute.Name).ToString();
                                    object newValue = null;

                                    if (oldValue != newValue /*!oldValue.Equals(newValue)*/)
                                    {
                                        DMOAuditDetail dMOAuditDetail = new DMOAuditDetail();
                                        dMOAuditDetail.AuditId = dMOAudit.Id;
                                        dMOAuditDetail.ColumnName = propertyInformation.ColumnAttribute.Name;
                                        dMOAuditDetail.OldValue = (oldValue != null) ? oldValue.ToString() : null;
                                        dMOAuditDetail.NewValue = (newValue != null) ? newValue.ToString() : null;
                                        _dAOAuditDetail.Save(dMOAuditDetail, _dAOHelper);
                                    }
                                }
                            }
                        }
                    }
                }

                #endregion

                _dAOGeneric.Delete(filter, _dAOHelper);
                _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Commit);
            }
            catch
            {
                _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Rollback);
                throw;
            }
        }

        /// <summary>
        /// Exclui todos os registros em uma tabela do banco de dados
        /// </summary>
        public virtual void DeleteAll()
        {
            _dAOHelper.EstablishFactoryConnection();
            _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Begin);

            try
            {
                #region Auditoria

                if ((!string.IsNullOrEmpty(_recordAudit)) && (_recordAudit.ToUpper() == true.ToString().ToUpper()))
                {
                    //Verifica se o modelo será auditado ou não
                    if (!_dataModel.IsNotAudit())
                    {
                        string primaryKeyColumnName = _dataModel.GetPrimaryKeyColumnName();
                        List<U> models = _dAOGeneric.LoadAll();

                        foreach (U model in models)
                        {
                            DMOAudit dMOAudit = new DMOAudit();
                            string primaryKey = model.GetPropertiesInformation().FindByColumnName(primaryKeyColumnName).PropertyValue.ToString();

                            dMOAudit.Action = DMOAudit.ActionType.Delete;
                            dMOAudit.TableName = _dataModel.GetTableName();
                            dMOAudit.PrimaryKey = string.Concat(primaryKeyColumnName, "=", primaryKey);
                            dMOAudit.ActionDate = DateTime.Now;
                            dMOAudit.ActionUser = _accountName;
                            _dAOAudit.Save(dMOAudit, _dAOHelper);

                            DMOBase.PropertiesInformation propertiesInformation = _dataModel.GetPropertiesInformation();

                            foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
                            {
                                if (!propertyInformation.ColumnAttribute.NotAudit)
                                {
                                    object oldValue = model.GetPropertiesInformation().FindByColumnName(propertyInformation.ColumnAttribute.Name).ToString();
                                    object newValue = null;

                                    if (oldValue != newValue /*!oldValue.Equals(newValue)*/)
                                    {
                                        DMOAuditDetail dMOAuditDetail = new DMOAuditDetail();
                                        dMOAuditDetail.AuditId = dMOAudit.Id;
                                        dMOAuditDetail.ColumnName = propertyInformation.ColumnAttribute.Name;
                                        dMOAuditDetail.OldValue = (oldValue != null) ? oldValue.ToString() : null;
                                        dMOAuditDetail.NewValue = (newValue != null) ? newValue.ToString() : null;
                                        _dAOAuditDetail.Save(dMOAuditDetail, _dAOHelper);
                                    }
                                }
                            }
                        }
                    }
                }

                #endregion

                _dAOGeneric.DeleteAll(_dAOHelper);
                _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Commit);
            }
            catch
            {
                _dAOHelper.TransactionHandler(DAOHelper.TransactionActionType.Rollback);
                throw;
            }
        }

        /// <summary>
        /// Conta um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a contagem</param>
        /// <returns>Quantidade contabilizada de registros</returns>
        public virtual Int32 Count(Filter<U> filter)
        {
            return _dAOGeneric.Count(filter);
        }

        /// <summary>
        /// Conta todos os registros de uma tabela do banco de dados
        /// </summary>
        /// <returns>Quantidade contabilizada de registros</returns>
        public virtual Int32 CountAll()
        {
            return _dAOGeneric.CountAll();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Persiste um novo registro em uma tabela do banco de dados
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        internal virtual void Save(U dataModel, DAOHelper dAOHelper)
        {
            if (dataModel == null) throw new ArgumentNullException("dataModel");
            if (dAOHelper == null) throw new ArgumentNullException("dAOHelper");

            _dAOGeneric.Save(dataModel, dAOHelper);

            #region Auditoria

            if ((!string.IsNullOrEmpty(_recordAudit)) && (_recordAudit.ToUpper() == true.ToString().ToUpper()))
            {
                //Verifica se o modelo será auditado ou não
                if (!dataModel.IsNotAudit())
                {
                    string primaryKeyColumnName = dataModel.GetPrimaryKeyColumnName();
                    string primaryKey = dataModel.GetPropertiesInformation().FindByColumnName(primaryKeyColumnName).PropertyValue.ToString();

                    DMOAudit dMOAudit = new DMOAudit();
                    dMOAudit.Action = DMOAudit.ActionType.Save;
                    dMOAudit.TableName = dataModel.GetTableName();
                    dMOAudit.PrimaryKey = string.Concat(primaryKeyColumnName, "=", primaryKey);
                    dMOAudit.ActionDate = DateTime.Now;
                    dMOAudit.ActionUser = _accountName;
                    _dAOAudit.Save(dMOAudit, dAOHelper);

                    DMOBase.PropertiesInformation propertiesInformation = dataModel.GetPropertiesInformation();

                    foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
                    {
                        if (!propertyInformation.ColumnAttribute.NotAudit)
                        {
                            object oldValue = null;
                            object newValue = propertyInformation.ToString();

                            DMOAuditDetail dMOAuditDetail = new DMOAuditDetail();
                            dMOAuditDetail.AuditId = dMOAudit.Id;
                            dMOAuditDetail.ColumnName = propertyInformation.ColumnAttribute.Name;
                            dMOAuditDetail.OldValue = (oldValue != null) ? oldValue.ToString() : null;
                            dMOAuditDetail.NewValue = (newValue != null) ? newValue.ToString() : null;
                            _dAOAuditDetail.Save(dMOAuditDetail, dAOHelper);
                        }
                    }
                }
            }

            #endregion
        }

        /// <summary>
        /// Carrega um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Lista de modelo de dados carregados</returns>
        internal virtual List<U> Load(Filter<U> filter, DAOHelper dAOHelper)
        {
            if (dAOHelper == null) throw new ArgumentNullException("dAOHelper");

            return _dAOGeneric.Load(filter, dAOHelper);
        }

        /// <summary>
        /// Carrega um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a carga</param>
        /// <param name="startRowIndex">posição inicial na base de dados para início da carga</param>
        /// <param name="maximumRows">Quantidade máxima de registros permitidos para retorno</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Lista de modelo de dados carregados</returns>
        internal virtual List<U> Load(Filter<U> filter, Int64 startRowIndex, Int64 maximumRows, DAOHelper dAOHelper)
        {
            if (dAOHelper == null) throw new ArgumentNullException("dAOHelper");

            return _dAOGeneric.Load(filter, startRowIndex, maximumRows, dAOHelper);
        }

        /// <summary>
        /// Carrega todos os registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Lista de modelo de dados carregados</returns>
        internal virtual List<U> LoadAll(DAOHelper dAOHelper)
        {
            if (dAOHelper == null) throw new ArgumentNullException("dAOHelper");

            return _dAOGeneric.LoadAll(dAOHelper);
        }

        /// <summary>
        /// Atualiza um registro já existente em uma tabela do banco de dados
        /// </summary>
        /// <param name="dataModel">Modelo de dados</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        internal virtual void Update(U dataModel, DAOHelper dAOHelper)
        {
            if (dataModel == null) throw new ArgumentNullException("dataModel");
            if (dAOHelper == null) throw new ArgumentNullException("dAOHelper");

            #region Auditoria

            if ((!string.IsNullOrEmpty(_recordAudit)) && (_recordAudit.ToUpper() == true.ToString().ToUpper()))
            {
                //Verifica se o modelo será auditado ou não
                if (!dataModel.IsNotAudit())
                {
                    string primaryKeyColumnName = dataModel.GetPrimaryKeyColumnName();
                    object primaryKeyObject = dataModel.GetPropertiesInformation().FindByColumnName(primaryKeyColumnName).PropertyValue;
                    string primaryKeyString = primaryKeyObject.ToString();
                    List<U> models = _dAOGeneric.Load(new Filter<U>().EqualTo(primaryKeyColumnName, primaryKeyObject));

                    foreach (U model in models)
                    {
                        DMOAudit dMOAudit = new DMOAudit();
                        dMOAudit.Action = DMOAudit.ActionType.Save;
                        dMOAudit.TableName = dataModel.GetTableName();
                        dMOAudit.PrimaryKey = string.Concat(primaryKeyColumnName, "=", primaryKeyString);
                        dMOAudit.ActionDate = DateTime.Now;
                        dMOAudit.ActionUser = _accountName;
                        _dAOAudit.Save(dMOAudit, dAOHelper);

                        DMOBase.PropertiesInformation propertiesInformation = dataModel.GetPropertiesInformation();

                        foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
                        {
                            if (!propertyInformation.ColumnAttribute.NotAudit)
                            {
                                object oldValue = model.GetPropertiesInformation().FindByColumnName(propertyInformation.ColumnAttribute.Name).ToString();
                                object newValue = propertyInformation.ToString();

                                if (!oldValue.Equals(newValue))
                                {
                                    DMOAuditDetail dMOAuditDetail = new DMOAuditDetail();
                                    dMOAuditDetail.AuditId = dMOAudit.Id;
                                    dMOAuditDetail.ColumnName = propertyInformation.ColumnAttribute.Name;
                                    dMOAuditDetail.OldValue = (oldValue != null) ? oldValue.ToString() : null;
                                    dMOAuditDetail.NewValue = (newValue != null) ? newValue.ToString() : null;
                                    _dAOAuditDetail.Save(dMOAuditDetail, dAOHelper);
                                }
                            }
                        }
                    }
                }
            }

            #endregion

            _dAOGeneric.Update(dataModel, dAOHelper);
        }

        /// <summary>
        /// Exclui um ou mais registros em uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a exclusão</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        internal virtual void Delete(Filter<U> filter, DAOHelper dAOHelper)
        {
            if (dAOHelper == null) throw new ArgumentNullException("dAOHelper");

            #region Auditoria

            if ((!string.IsNullOrEmpty(_recordAudit)) && (_recordAudit.ToUpper() == true.ToString().ToUpper()))
            {
                //Verifica se o modelo será auditado ou não
                if (!_dataModel.IsNotAudit())
                {
                    string primaryKeyColumnName = _dataModel.GetPrimaryKeyColumnName();
                    List<U> models = _dAOGeneric.Load(filter);

                    foreach (U model in models)
                    {
                        DMOAudit dMOAudit = new DMOAudit();
                        string primaryKey = model.GetPropertiesInformation().FindByColumnName(primaryKeyColumnName).PropertyValue.ToString();

                        dMOAudit.Action = DMOAudit.ActionType.Delete;
                        dMOAudit.TableName = _dataModel.GetTableName();
                        dMOAudit.PrimaryKey = string.Concat(primaryKeyColumnName, "=", primaryKey);
                        dMOAudit.ActionDate = DateTime.Now;
                        dMOAudit.ActionUser = _accountName;
                        _dAOAudit.Save(dMOAudit, dAOHelper);

                        DMOBase.PropertiesInformation propertiesInformation = _dataModel.GetPropertiesInformation();

                        foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
                        {
                            if (!propertyInformation.ColumnAttribute.NotAudit)
                            {
                                object oldValue = model.GetPropertiesInformation().FindByColumnName(propertyInformation.ColumnAttribute.Name).ToString();
                                object newValue = null;

                                if (!oldValue.Equals(newValue))
                                {
                                    DMOAuditDetail dMOAuditDetail = new DMOAuditDetail();
                                    dMOAuditDetail.AuditId = dMOAudit.Id;
                                    dMOAuditDetail.ColumnName = propertyInformation.ColumnAttribute.Name;
                                    dMOAuditDetail.OldValue = (oldValue != null) ? oldValue.ToString() : null;
                                    dMOAuditDetail.NewValue = (newValue != null) ? newValue.ToString() : null;
                                    _dAOAuditDetail.Save(dMOAuditDetail, dAOHelper);
                                }
                            }
                        }
                    }
                }
            }

            #endregion

            _dAOGeneric.Delete(filter, dAOHelper);
        }

        /// <summary>
        /// Exclui todos os registros em uma tabela do banco de dados
        /// </summary>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        internal virtual void DeleteAll(DAOHelper dAOHelper)
        {
            if (dAOHelper == null) throw new ArgumentNullException("dAOHelper");

            #region Auditoria

            if ((!string.IsNullOrEmpty(_recordAudit)) && (_recordAudit.ToUpper() == true.ToString().ToUpper()))
            {
                //Verifica se o modelo será auditado ou não
                if (!_dataModel.IsNotAudit())
                {
                    string primaryKeyColumnName = _dataModel.GetPrimaryKeyColumnName();
                    List<U> models = _dAOGeneric.LoadAll();

                    foreach (U model in models)
                    {
                        DMOAudit dMOAudit = new DMOAudit();
                        string primaryKey = model.GetPropertiesInformation().FindByColumnName(primaryKeyColumnName).PropertyValue.ToString();

                        dMOAudit.Action = DMOAudit.ActionType.Delete;
                        dMOAudit.TableName = _dataModel.GetTableName();
                        dMOAudit.PrimaryKey = string.Concat(primaryKeyColumnName, "=", primaryKey);
                        dMOAudit.ActionDate = DateTime.Now;
                        dMOAudit.ActionUser = _accountName;
                        _dAOAudit.Save(dMOAudit, dAOHelper);

                        DMOBase.PropertiesInformation propertiesInformation = _dataModel.GetPropertiesInformation();

                        foreach (DMOBase.PropertyInformation propertyInformation in propertiesInformation)
                        {
                            if (!propertyInformation.ColumnAttribute.NotAudit)
                            {
                                object oldValue = model.GetPropertiesInformation().FindByColumnName(propertyInformation.ColumnAttribute.Name).ToString();
                                object newValue = null;

                                if (!oldValue.Equals(newValue))
                                {
                                    DMOAuditDetail dMOAuditDetail = new DMOAuditDetail();
                                    dMOAuditDetail.AuditId = dMOAudit.Id;
                                    dMOAuditDetail.ColumnName = propertyInformation.ColumnAttribute.Name;
                                    dMOAuditDetail.OldValue = (oldValue != null) ? oldValue.ToString() : null;
                                    dMOAuditDetail.NewValue = (newValue != null) ? newValue.ToString() : null;
                                    _dAOAuditDetail.Save(dMOAuditDetail, dAOHelper);
                                }
                            }
                        }
                    }
                }
            }

            #endregion

            _dAOGeneric.DeleteAll(dAOHelper);
        }

        /// <summary>
        /// Conta um ou mais registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="filter">Objeto de filtro para a contagem</param>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Quantidade contabilizada de registros</returns>
        internal virtual Int32 Count(Filter<U> filter, DAOHelper dAOHelper)
        {
            if (dAOHelper == null) throw new ArgumentNullException("dAOHelper");

            return _dAOGeneric.Count(filter, dAOHelper);
        }

        /// <summary>
        /// Conta todos os registros de uma tabela do banco de dados
        /// </summary>
        /// <param name="dAOHelper">Objeto para manipulação de dados em modo transacional</param>
        /// <returns>Quantidade contabilizada de registros</returns>
        internal virtual Int32 CountAll(DAOHelper dAOHelper)
        {
            if (dAOHelper == null) throw new ArgumentNullException("dAOHelper");

            return _dAOGeneric.CountAll(dAOHelper);
        }

        #endregion
    }
}
